//
// Created by Administrator on 2020/7/25.
//T6章:继承与派生
//派生类的构造函数
//(1)默认情况下:A基类的构造函数不被继承;B派生类需要定义自己的构造函数;
//(2)C++11规定:
//  A-可用using语句继承基类构造函数。
//  B-但是只能初始化从基类继承的成员。
//      B1-派生类新增成员可以通过类内初始值进行初始化。
//  C-语法形式：using B::B;
//(3)建议:如果派生类有自己新增的成员，且需要通过构造函数初始化，则派生类要自定义构造函数。
//(4)若不继承基类的构造函数
//  A-派生类新增成员：派生类定义构造函数初始化；
//  B-继承来的成员：自动调用基类构造函数进行初始化；
//  C-派生类的构造函数需要给基类的构造函数传递参数。
//(5)单继承
//  派生类只有一个直接基类的情况，是单继承。单继承时，派生类的构造函数只需要给一个直接基类构造函数传递参数。
//(5.1)单继承时构造函数的定义语法:
/*
派生类名::派生类名(基类所需的形参，本类成员所需的形参):
基类名(参数表), 本类成员初始化列表
{
    //其他初始化；
}；
*/
//单继承时的构造函数举例（补7-3）
#include<iostream>
using namespace std;
//-------------B类--------------//
class B//基类B
{
public:
    B();//默认构造函数
    B(int i);//含一参数的构造函数
    ~B();//析构函数
    void print() const;
private:
    int b;
};

B::B() {
    b=0;
    cout << "B's default constructor called." << endl;
}
B::B(int i) {
    b=i;
    cout << "B's constructor called." << endl;
}
B::~B() {
    cout << "B's destructor called." << endl;
}
void B::print() const {
    cout << b << endl;
}
//-------------C类--------------//
class C: public B//C类以共有方式继承B类
{
public:
    C();
    C(int i, int j);
    ~C();
    void print() const;
private:
    int c;
};
C::C() {
    c = 0;
    cout << "C's default constructor called." << endl;
}
C::C(int i,int j): B(i), c(j){
    cout << "C's constructor called." << endl;
}

C::~C() {
    cout << "C's destructor called." << endl;
}
void C::print() const {
    B::print();
    cout << c << endl;
}
//-------------main--------------//
int main() {
    C obj(5, 6);//
    obj.print();
    return 0;
}
//(6)多继承
//  多继承时，有多个直接基类，如果不继承基类的构造函数，派生类构造函数需要给所有基类构造函数传递参数。我们来看一下语法规定
//(6.1)多继承时构造函数的定义语法:
/*
派生类名::派生类名(参数表) :
基类名1(基类1初始化参数表),
基类名2(基类2初始化参数表),
...
基类名n(基类n初始化参数表),
本类成员初始化列表
{
        //其他初始化；
}；
*/
//(6.2)派生类与基类的构造函数
//  A-当基类有默认构造函数时
//      A1-派生类构造函数可以不向基类构造函数传递参数。
//      A2-构造派生类的对象时，基类的默认构造函数将被调用。
//  B-如需执行基类中带参数的构造函数
//      B1-派生类构造函数应为基类构造函数提供参数。
//(6.3)多继承且有对象成员时派生的构造函数定义语法
/*
派生类名::派生类名(形参表):
基类名1(参数), 基类名2(参数), ..., 基类名n(参数),
本类成员（含对象成员）初始化列表
{
        //其他初始化
}；
*/
//(6.4)构造函数的执行顺序
//  A-调用基类构造函数。
//      A1-顺序按照它们被继承时声明的顺序（从左向右）。
//  B-对初始化列表中的成员进行初始化。
//      B1-顺序按照它们在类中定义的顺序。
//      B2-对象成员初始化时自动调用其所属类的构造函数。由初始化列表提供参数。
//  C-执行派生类的构造函数体中的内容。
